package JavaEE初阶;
import javax.sound.midi.Soundbank;
import java.sql.PreparedStatement;
import java.util.PriorityQueue;
import java.util.Timer;
import java.util.TimerTask;



class MyTimerTask implements  Comparable<MyTimerTask>{
    //要有一个要执行的任务
    private Runnable runnable;

    //一个要执行任务的绝对时间
    private long time;

    //此时的delay就是schedule方法中的相对时间
    public MyTimerTask(Runnable runnable,long delay){
        this.runnable = runnable;
        this.time = System.currentTimeMillis() + delay;

    }

    @Override
    public int compareTo(MyTimerTask o){
        //这样的写法就是让队首元素时最小时间的值
        return (int)(this.time - o.time);


        //下面的写法是让队首元素是最大元素的值
        //return o.time - this.time;
    }

    //加上一个获取时间的方法
    public long getTime(){
        return time;
    }

    //获取Runnable
    public Runnable getRunnable(){
        return runnable;
    }
}


//构造自己的定时器
class MyTimer{
    //使用一个数据结构，保存所有要安排的任务
    private PriorityQueue<MyTimerTask> queue = new PriorityQueue<>();

    public Object locker = new Object();

    public void schedule(Runnable runnable,long delay){
        synchronized (locker){
            queue.offer(new MyTimerTask(runnable,delay));
            locker.notify();
        }
    }

    //创建一个扫描线程
    public MyTimer(){
            //创建一个扫描线程
            Thread t = new Thread(() ->{
                //扫描线程，需要不停地扫描队首元素，看是否到达时间
                while(true){
                    synchronized (locker){
                        //不要使用if作为wait的判定条件，要使用while
                        //使用while的目的是为了在wait被唤醒之后，再一次确认一下条件
                        while (queue.isEmpty()){
                            //队列为空，使用wait进行阻塞等待
                            try {
                                locker.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        //不停地取出队首元素
                        MyTimerTask task = queue.peek();
                        //比较一下看队首元素是否可以执行了
                        long curTime = System.currentTimeMillis();
                        if(curTime > task.getTime()){
                            //当前时间已经到达了任务时间，就可以执行任务了
                            task.getRunnable().run();
                            //任务执行完毕，从队列中删除
                            queue.poll();
                        }else{
                            //当前时间还没有到达任务时间，就还不可以执行任务
                            //时间没有到，就什么都不写
                            try {
                                locker.wait(task.getTime() - curTime);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }

                }
            });
            t.start();
    }
}




public class Demo07 {
    public static void main(String[] args) {
      MyTimer timer = new MyTimer();
      timer.schedule(new Runnable(){
          @Override
          public void run(){
              System.out.println("3000");
          }
      },3000);

      timer.schedule(new Runnable(){
          @Override
          public void run(){
              System.out.println("2000");
          }
      },2000);

      timer.schedule(new Runnable(){
          @Override
          public void run(){
              System.out.println("1000");
          }
      },1000);
        System.out.println("程序启动");
    }
}
